<!DOCTYPE html>
<html>

<head>
    <style>
        /* 定义容器的样式，设置宽度和高度，并设置 overflow 属性为 auto 或 scroll 以产生滚动效果 */
        .container {
            width: 300px;
            height: 200px;
            overflow: auto;
        }

        /* 定义虚拟滚动列表的样式 */
        .list {
            height: 1000px;
            /* 设置虚拟滚动列表的高度 */
            padding: 10px;
            /* 设置列表项的内边距 */
        }

        /* 定义列表项的样式 */
        .list-item {
            height: 50px;
            /* 设置列表项的高度 */
            line-height: 50px;
            /* 设置列表项的行高，用于垂直居中文本 */
            border-bottom: 1px solid #ccc;
            /* 设置列表项之间的分隔线 */
        }
    </style>
</head>

<body>
<div class="container" id="container">
    <div class="list" id="list">
        <!-- 渲染虚拟滚动列表项 -->
        <div id="inner1">
            <div class="list-item" v-for="item in visibleItems" :key="item.id">{{ item.name }}</div>
        </div>
    </div>
</div>

<script>
    // 模拟数据
    const items = Array.from({length: 1000}, (v, i) => ({id: i, name: `Item ${i + 1}`}));

    // 初始化容器和列表元素
    const container = document.getElementById('container');
    const list = document.getElementById('list');

    // 设置容器的高度，用于显示滚动条
    container.style.height = '200px';

    // 计算列表项的高度
    const listItemHeight = 50;

    // 计算容器可以显示的列表项数量
    const visibleItemCount = Math.ceil(container.offsetHeight / listItemHeight);

    // 设置列表的实际高度，用于产生滚动效果
    list.style.height = `${listItemHeight * items.length}px`;

    // 计算当前滚动位置
    let scrollTop = 0;

    // 初始化可见的列表项数组
    let visibleItems = items.slice(0, visibleItemCount);

    // 更新可见列表项
    const updateVisibleItems = () => {
        // 计算当前滚动位置对应的列表项索引
        const startIndex = Math.floor(scrollTop / listItemHeight);

        // 计算结束索引
        const endIndex = startIndex + visibleItemCount;

        // 更新可见的列表项
        visibleItems = items.slice(startIndex, endIndex);

        // 渲染列表项
        renderList();
        if (scrollTop >= listItemHeight) {
            inner1.style.transform = "translateY(" + listItemHeight * startIndex + "px)"
        }
    };

    // 渲染列表项
    const renderList = () => {
        const listElement = document.getElementById('list');
        inner1.innerHTML = '';

        visibleItems.forEach(item => {
            const listItemElement = document.createElement('div');
            listItemElement.className = 'list-item';
            listItemElement.textContent = item.name;
            inner1.appendChild(listItemElement);
        });
    };

    // 监听容器的滚动事件
    container.addEventListener('scroll', e => {
        // 更新当前滚动位置
        scrollTop = e.target.scrollTop;
        // 更新可见的列表项
        updateVisibleItems();
    });

    // 初始化时渲染列表项
    renderList();
</script>
</body>

</html>